﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using WCFContracts;
using System.Configuration;
using WCFGzip;
using System.Xml;
using System.ServiceModel.Security;
using System.Data;
using Pub.Tools;
using System.ServiceModel.Description;


namespace Pub.Lib
{

    public static class WCF
    {

        public static void WCFOpen()
        {
            ICommunicationObject channel = PubVar.WcfProxy as ICommunicationObject;
            channel.Open();
        }

        public static void WCFClose()
        {
            ICommunicationObject channel = PubVar.WcfProxy as ICommunicationObject;

            channel.Close();
        }



        public static void LoadWCF()
        {
            if (PubVar.SysSecure_Username != string.Empty)
            {
                PubVar.SysDATName = "WCF 压缩 CustomBinding";
                LoadZipCustomWCF(); //压缩
            }
            else
            {
                PubVar.SysDATName = "WCF BasicBinding";
                LoadBasicWCF(); //BASIC,兼容Web Service
            }
        }

        private static string GetSysListenUrl(string PathPort)
        {
            string ServerPort = string.Empty;
            string ListenPort = string.Empty;

            //计算监听端口
            ServerPort = PathPort.Substring(PathPort.LastIndexOf(":") + 1, PathPort.Length - PathPort.LastIndexOf(":") - 1);
            ServerPort = ServerPort.Substring(0, PathPort.IndexOf("/") - 1);
            ListenPort = (SysTools.ToInt(ServerPort) + 1).ToString();

            string strreturn = PathPort.Replace(ServerPort, ListenPort);
            return strreturn;
        }

        public static void LoadZipCustomWCF()
        {
            try
            {

                string strPath = XmlTools.GetRandomServiceURL(PubVar.SysServerUrlList); //获取服务器端口

                strPath = strPath.Replace("tcp://", "http://");

                PubVar.SysServerURL = strPath;

                strPath = strPath + Pub.PubVar.strDBAccess; //+"WCFAccess";

                PubVar.SysListenURL = GetSysListenUrl(strPath);

                TextMessageEncodingBindingElement tmee = new TextMessageEncodingBindingElement();
                //   BinaryMessageEncodingBindingElement tmee = new BinaryMessageEncodingBindingElement();

                tmee.MaxReadPoolSize = 640;
                tmee.MaxWritePoolSize = 160;
                //    tmee.WriteEncoding = Encoding.UTF8;
                tmee.ReaderQuotas.MaxDepth = 320;
                tmee.ReaderQuotas.MaxStringContentLength = 2147483647;
                tmee.ReaderQuotas.MaxArrayLength = 163840;
                tmee.ReaderQuotas.MaxBytesPerRead = 40960;
                tmee.ReaderQuotas.MaxNameTableCharCount = 163840;


                ICollection<BindingElement> bindingElements = new List<BindingElement>();

                //BinaryMessageEncodingBindingElement 加密
                //CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(new BinaryMessageEncodingBindingElement(), CompressAlgorithm.GZip);
                //TextMessageEncodingBindingElement 加密
                //CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(new TextMessageEncodingBindingElement(), CompressAlgorithm.GZip);
                CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(tmee, CompressAlgorithm.GZip);

                HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
                httpBindingElement.MaxReceivedMessageSize = 2147483647;


                //               httpBindingElement.AuthenticationScheme = System.Net.AuthenticationSchemes.Ntlm;


                bindingElements.Add(textBindingElement);
                bindingElements.Add(httpBindingElement);


                CustomBinding bind = new CustomBinding(bindingElements);




                //      System.ServiceModel.Channels.Binding basicHttpBinding = new BasicHttpBinding("CustomBinding_IService1");




                //bind.ReaderQuotas = new XmlDictionaryReaderQuotas();
                //bind.MaxStringContentLength = 2147483647; //(更改这个数字) };


                //   EndpointAddress ss = new System.ServiceModel.EndpointAddress(strPath);


                ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(bind, new System.ServiceModel.EndpointAddress(strPath));
                PubVar.WcfProxy = channelFactory.CreateChannel();



                //UserNamePasswordClientCredential credential = channelFactory.Credentials.UserName;
                //credential.UserName = "111";



                //  channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

                //channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;



                //   System.ServiceModel.Channels.Binding basicHttpBinding = new BasicHttpBinding();

                //    System.ServiceModel.Channels.Binding tcpBinding = new NetTcpBinding();
                //    EndpointAddress tcpAddress = new EndpointAddress("http://127.0.0.1:9999/dbaccess");
                //     EndpointAddress tcpAddress = new EndpointAddress(strPath);

                //      binding.SendTimeout = new TimeSpan(0, 30, 0); ;
                // binding.MaxReceivedMessageSize = 2147483647;
                // binding.ReaderQuotas.MaxStringContentLength = 2147483647;

                //ChannelFactory<ICalculator> channelFactory1 = new ChannelFactory<ICalculator>(binding, tcpAddress);

                //       PubVar.WcfProxy = channelFactory.CreateChannel();


                //try
                //{
                //    PubVar.strConn = DbHelper.GetConnstring(); //测试与Remoting服务器连接
                //}
                //catch (Exception ex)
                //{

                //    PubTools.MsgClass.ErrorMsg(ex.Message.ToString());
                //    System.Environment.Exit(System.Environment.ExitCode);
                //}


            }
            catch (Exception ex)
            {
                Pub.Tools.MsgTools.ErrorMsg(ex.Message.ToString());
                System.Environment.Exit(System.Environment.ExitCode);
            }
        }

        public static void LoadBasicWCF()
        {
            try
            {
                string strPath = XmlTools.GetRandomServiceURL(PubVar.SysServerUrlList); //获取服务器端口

                strPath = strPath.Replace("tcp://", "http://");

                PubVar.SysServerURL = strPath;

                strPath = strPath + Pub.PubVar.strDBAccess;// "WCFAccess";

                PubVar.SysListenURL = GetSysListenUrl(strPath);


                // Set new MaxBufferSize
                BasicHttpBinding binding = new BasicHttpBinding();



                binding.SendTimeout = new TimeSpan(0, 30, 0); ;
                binding.MaxReceivedMessageSize = 2147483647;
                binding.ReaderQuotas.MaxStringContentLength = 2147483647;


                //    ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(binding, tcpAddress);
                ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>(binding, strPath);

                //ICalculator proxy = channelFactory.CreateChannel();
                PubVar.WcfProxy = channelFactory.CreateChannel();

                //  ICalculator proxy = channelFactory.CreateChannel();

                //  string pp = proxy.Connstring(PubVar.ConnMain);

                //    channelFactory.CreateChannel

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    public class WCFAccess : ICalculator
    {
        DBAccess dbAccess = new DBAccess();

        /// <summary>
        /// 返回(SQL语句、连接名称)生成的DataTable
        /// </summary>
        /// <param name="strConnName">连接名称</param>
        /// <param name="strSql">SQL语句</param>
        /// <returns>返回(SQL语句、连接名称)生成的DataTable</returns>
        public DataTable IGetDataTable(string ArrAuth, string strSql, string strConnName, ref string strMess)
        {
            DataTable datatable = new DataTable();
            if (dbAccess.CheckUser(ArrAuth, ref strMess))
            {
                datatable = dbAccess.GetDataTable(ArrAuth, strSql, strConnName, ref strMess);
            }
            return datatable;
        }

        /// <summary>
        /// 更新系列化db
        /// </summary>
        /// <param name="strSQL">SQL语句</param>
        /// <param name="strxml">压缩的XML</param>
        /// <param name="strConnName">连接名称</param>
        /// <param name="dbname">更新的Table名称</param>
        /// <param name="dbfields">更新的字段</param>
        /// <param name="strMess">错误提示</param>
        /// <returns>返回是否成功更新</returns>
        public Boolean ISaveDT(string ArrAuth, string strSQL, string strxml, string strConnName, string dbname, string dbfields, ref string strMess)
        {
            Boolean bl = false;
            if (dbAccess.CheckUser(ArrAuth, ref  strMess))
            {
                bl = dbAccess.SaveDT(ArrAuth, strSQL, strxml, strConnName, dbname, dbfields, ref  strMess);
            }
            return bl;
        }

        /// <summary>
        /// WCF接口,获取连接名称的服务器时间
        /// </summary>
        /// <param name="strConnName">连接名称</param>
        /// <returns>WCF接口,返回连接名称的服务器时间</returns>
        public DateTime IGetServerTime(string ArrAuth, string strConnName, ref string strMess)
        {
            DateTime datetime = System.DateTime.Now;
            if (dbAccess.CheckUser(ArrAuth,ref strMess))
            {
                datetime = dbAccess.GetServerTime(strConnName,ref  strMess);
            }
            return datetime;
        }


        /// <summary>
        /// WCF接口,获取(连接名称)的字符串
        /// </summary>
        /// <param name="strConnName">连接名称</param>
        /// <returns>WCF接口,返回(连接名称)的字符串</returns>
        public string IGetConnstring(string ArrAuth, string strConnName, ref string strMess)
        {
            string strConn = string.Empty;
            string ConnectionProviderName = string.Empty;
            if (dbAccess.CheckUser(ArrAuth,ref strMess))
            {
                strConn = dbAccess.GetConnectionStringByName(strConnName, ref ConnectionProviderName);
            }
            return strConn;
        }

        public string IGetDataTableXml(string ArrAuth,  string strSql, string strConnName,ref string strMess)
        {
            string strResult = dbAccess.GetDataTableXml(ArrAuth, strSql, strConnName,ref  strMess);
            return strResult;
        }

        /// <summary>
        /// 序列化的DataTable
        /// </summary>
        /// <param name="strConnName">连接名称</param>
        /// <param name="strSql">SQL语句</param>
        /// <returns>经序列化的DataTable的XML</returns>
        public string IGetDataTableXmlSerialize(string ArrAuth, string strSql, string strConnName, ref string strMess)
        {
            string strResult = dbAccess.GetDataTableXmlSerialize(ArrAuth, strSql, strConnName,ref strMess);
            return strResult;
        }

        public string IGetDataTableXmlSerializeZip(string ArrAuth, string strSql, string strConnName, ref string strMess)
        {
            string strResult = ZipString.CompressString(dbAccess.GetDataTableXmlSerialize(ArrAuth, strSql, strConnName,ref strMess));
            return strResult;
        }

        /// <summary>
        /// 压缩的由(SQL语句、连接名称)生成的DataTable生成的字符串
        /// </summary>
        /// <param name="strSql">SQL语句</param>
        /// <param name="strConnName">连接名称</param>
        /// <returns>返回压缩的由(SQL语句、连接名称)生成的DataTable生成的字符串</returns>
        public string IGetDataTableXmlZip(string ArrAuth,  string strSql, string strConnName, ref string strMess)
        {
            string strResult = dbAccess.GetDataTableXmlZip(ArrAuth, strSql, strConnName, ref  strMess);
            return strResult;
        }


        public Boolean IExecSQL(string ArrAuth, string strSql, string strConnName, ref string strMess) //主要执行SQL源
        {
            Boolean bl = false;
            if (dbAccess.CheckUser(ArrAuth,ref strMess))
            {
                bl = dbAccess.ExecSQL(strSql, strConnName, ref  strMess);
            }
            return bl;
        }


        public Boolean IChangeUserPasswd(string strEnAuth, ref string strMess)
        {
            return dbAccess.IChangeUserPasswd(strEnAuth, ref strMess);
            //  return PubTools.ADClass.ChangeUserPasswd(domain, userName, oldPwd, newPwd, ref  strMess);
        }

        public Boolean IAuthUser(string strEnAuth, ref string strMess)
        {
            return dbAccess.IAuthUser(strEnAuth, ref strMess);
            //  return PubTools.ADClass.AuthUser(domain, userName, password, ref  strMess);
        }

    }

    public static class WCFServer
    {

        /// <summary>
        /// 初始化WCF host
        /// </summary>
        /// <param name="host">host</param>
        /// <param name="strPort">端口</param>
        /// <param name="strWCFListPort">List端口</param>
        /// <returns></returns>
        public static string Basic(ref ServiceHost host, string strPort, string strWCFListPort)
        {
            string StrResult = string.Empty;
            string strbaseDBAccess = "http://127.0.0.1:" + strPort + "/" + PubVar.strDBAccess;
            string strbaserSysUser = "http://127.0.0.1:" + strPort + "/" + PubVar.strSysUser;

            Uri baseDBAccess = new Uri(strbaseDBAccess);

            Uri baserSysUser = new Uri(strbaserSysUser, UriKind.RelativeOrAbsolute);

            Uri baseAddress = new Uri(strbaseDBAccess);

            // Instantiate new ServiceHost   
            host = new ServiceHost(typeof(WCFAccess), new Uri[] { baseAddress });


            BasicHttpBinding basicbinding = new BasicHttpBinding();


            basicbinding.OpenTimeout = new TimeSpan(0, 5, 0);
            basicbinding.CloseTimeout = new TimeSpan(0, 5, 0);
            basicbinding.SendTimeout = new TimeSpan(0, 5, 0); 
 

            basicbinding.MaxReceivedMessageSize = 2147483647;
            basicbinding.ReaderQuotas.MaxStringContentLength = 2147483647;

            // Add an Endpoint
            host.AddServiceEndpoint(typeof(ICalculator), basicbinding, "");

            //if (host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceDebugBehavior>() == null)
            //{
            //    ServiceDebugBehavior debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();
            //    debug.IncludeExceptionDetailInFaults = true;
            //}

            ServiceDebugBehavior debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();
            if (null == debug)
            {
                debug = new ServiceDebugBehavior();
                host.Description.Behaviors.Add(debug);
            }
            debug.IncludeExceptionDetailInFaults = true;

            //     behavior = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
            {
                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();

                behavior.HttpGetEnabled = true;

                behavior.HttpGetUrl = new Uri("http://127.0.0.1:" + strWCFListPort + "/" + PubVar.strDBAccess);

                host.Description.Behaviors.Add(behavior);

            }

            try
            {
                host.Open();
                StrResult = "WCF[端口:" + strPort + ",Listen 端口:" + strWCFListPort + "]BasicHttpBinding 服务启动成功！";
            }
            catch (Exception ex)
            {
                StrResult = "WCF[端口:" + strPort + ",Listen 端口:" + strWCFListPort + "]BasicHttpBinding 服务启动失败！\r\n" + ex.Message.ToString();
            }
            return StrResult;
        }

        public static string ZipCustom(ref ServiceHost host, string strPort, string strWCFListPort)
        {
            string StrResult = string.Empty;

            string strbaseDBAccess = "http://127.0.0.1:" + strPort + "/" + PubVar.strDBAccess;
            string strbaserSysUser = "http://127.0.0.1:" + strPort + "/" + PubVar.strSysUser;


            Uri baseDBAccess = new Uri(strbaseDBAccess);

            Uri baserSysUser = new Uri(strbaserSysUser, UriKind.RelativeOrAbsolute);

            Uri baseAddress = new Uri(strbaseDBAccess);
            host = new ServiceHost(typeof(WCFAccess), new Uri[] { baseAddress });



            //服务绑定
            ICollection<BindingElement> bindingElements = new List<BindingElement>();
            HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
            TextMessageEncodingBindingElement tmee = new TextMessageEncodingBindingElement();
            //   BinaryMessageEncodingBindingElement tmee = new BinaryMessageEncodingBindingElement();

            tmee.MaxReadPoolSize = 640;
            tmee.MaxWritePoolSize = 160;
            //    tmee.WriteEncoding = Encoding.UTF8;
            tmee.ReaderQuotas.MaxDepth = 320;
            tmee.ReaderQuotas.MaxStringContentLength = 2147483647;
            tmee.ReaderQuotas.MaxArrayLength = 163840;
            tmee.ReaderQuotas.MaxBytesPerRead = 40960;
            tmee.ReaderQuotas.MaxNameTableCharCount = 163840;


            httpBindingElement.MaxReceivedMessageSize = 2147483647;

            //    httpBindingElement.AuthenticationScheme = System.Net.AuthenticationSchemes.IntegratedWindowsAuthentication;

            //        CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(new BinaryMessageEncodingBindingElement(), CompressAlgorithm.GZip);
            //       CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(new TextMessageEncodingBindingElement(), CompressAlgorithm.GZip);
            CompressEncodingBindingElement textBindingElement = new CompressEncodingBindingElement(tmee, CompressAlgorithm.GZip);


            bindingElements.Add(textBindingElement);
            bindingElements.Add(httpBindingElement);

            //       bindingElements.Add(tsb);


            CustomBinding bind = new CustomBinding(bindingElements);

          //  bind.SendTimeout = new TimeSpan(0, 30, 0);
            bind.OpenTimeout = new TimeSpan(0, 5, 0);
            bind.CloseTimeout = new TimeSpan(0, 5, 0);
            bind.SendTimeout = new TimeSpan(0, 5, 0); 

            //     System.ServiceModel.Description.ServiceCredentials ss = host.Credentials;

            host.AddServiceEndpoint(typeof(ICalculator), bind, "");

            ServiceDebugBehavior debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();

            if (null == debug)
            {
                debug = new ServiceDebugBehavior();
                host.Description.Behaviors.Add(debug);
            }

            debug.IncludeExceptionDetailInFaults = true;


            if (host.Description.Behaviors.Find<System.ServiceModel.Description.ServiceMetadataBehavior>() == null)
            {
                System.ServiceModel.Description.ServiceMetadataBehavior svcMetaBehavior = new System.ServiceModel.Description.ServiceMetadataBehavior();
                svcMetaBehavior.HttpGetEnabled = true;

                svcMetaBehavior.HttpGetUrl = new Uri("http://127.0.0.1:" + strWCFListPort + "/" + PubVar.strDBAccess);

                host.Description.Behaviors.Add(svcMetaBehavior);

            }

            try
            {
                host.Open();

                StrResult = "WCF[端口:" + strPort + ",Listen 端口:" + strWCFListPort + "]压缩 CustomBinding 服务启动成功！";
            }
            catch (Exception ex)
            {
                StrResult = "WCF[端口:" + strPort + ",Listen 端口:" + strWCFListPort + "]压缩 CustomBinding 服务启动失败！\r\n" + ex.Message.ToString();
            }
            return StrResult;
        }

    }
}
